package com.watson.thread;

import com.google.common.util.concurrent.Runnables;
import org.apache.lucene.util.NamedThreadFactory;

import java.util.concurrent.*;
import java.util.concurrent.atomic.LongAdder;
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.concurrent.locks.StampedLock;

import static java.util.concurrent.TimeUnit.SECONDS;

/**
 * @program: mytest
 * @description: thread test
 * @author: zhangpeng348@jd.com
 * @date: 2018-12-12 21:25
 **/
public class ThreadTest {
    public static void main(String[] args) {
//        runtest();
        try {
//            daemonTest();
            fireLockTest();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void runtest() {
        RunnTest runnTest = new RunnTest();
        runnTest.run();
        Thread thread = new Thread(runnTest);
        thread.start();

        boolean lock = Thread.holdsLock("lock");
        System.out.println(lock);
    }

    public static class RunnTest implements Runnable {
        public CountDownLatch latch = new CountDownLatch(2);
        public RunnTest() {

        }

        @Override
        public void run() {
            System.out.println("aaaa");
            try {
                Thread.sleep(1000);
                System.out.println("aaaa");
                latch.countDown();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        }
    }

    public static void callTest() {
        CallTest callTest = new CallTest();

        ExecutorService service = Executors.newFixedThreadPool(2);
        Future<Boolean> submit = service.submit(callTest);
        try {
            Boolean aBoolean = submit.get();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
    }

    public static class CallTest implements Callable<Boolean> {

        @Override
        public Boolean call() throws Exception {
            System.out.println("call test");
            return null;
        }
    }

    public static void daemonTest() throws InterruptedException {
        Runnable r = new Runnable() {
            @Override
            public void run() {
                for (int time =10; time > 0; --time) {
                    System.out.println("Time #" + time);
                    try {
                        SECONDS.sleep(1);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        };

        Thread t = new Thread(r);
//        t.setDaemon(true);  // try to set this to "false" and see what happens
        t.start();

        System.out.println("Main thread waiting...");
        SECONDS.sleep(6);
        System.out.println("Main thread exited.");
    }

    public void longAddrTest() {
        LongAdder longAdder;
        CopyOnWriteArrayList copyOnWriteArrayList;
        ConcurrentHashMap concurrentHashMap;
        ReentrantReadWriteLock reentrantReadWriteLock;
        ReentrantLock reentrantLock;
        StampedLock stampedLock;
    }


    /**
     *     true 表示 ReentrantLock 的公平锁
     */
    private static ReentrantLock lock = new ReentrantLock(true);

    public static void testFail(){
        try {
            lock.lock();
            System.out.println(Thread.currentThread().getName() +"获得了锁");
        }finally {
            lock.unlock();
        }
    }
    public static void fireLockTest() {

        Runnable runnable = () -> {
            System.out.println(Thread.currentThread().getName()+"启动");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            testFail();
        };
        Thread[] threadArray = new Thread[10];
        for (int i=0; i<10; i++) {
            threadArray[i] = new Thread(runnable);
            threadArray[i].start();
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        for (int i=0; i<10; i++) {
        }
    }

}
